package myutil

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"errors"
	"fmt"
	"hash/fnv"
	"log"
	"os"
	"regexp"
	"strings"
	"unicode"
)

// Try 是一个泛型函数，用于执行有错误返回的函数并处理错误
func Try[T any](fn func() (T, error)) T {
	result, err := fn()
	if err != nil {
		// 这里可以添加更复杂的错误处理逻辑
		fmt.Printf("Error: %v\n", err)
		var zero T // 创建类型T的零值
		return zero
	}
	return result
}

// HashCode 计算string的hashCode值
func HashCode(s string) int {
	h := fnv.New32a()
	h.Write([]byte(s))
	return int(h.Sum32())
}

/* 序列化相关 */

// Serialize 定义一个序列化函数，它可以接受任何类型的参数
func Serialize[T any](obj T) []byte {
	var buffer bytes.Buffer
	enc := gob.NewEncoder(&buffer)
	if err := enc.Encode(obj); err != nil {
		fmt.Println(err)
		return nil
	}
	return buffer.Bytes()
}

// Deserialize 定义一个反序列化函数，它需要传入目标类型的零值作为泛型参数
func Deserialize[T any](data []byte) T {
	var result T
	buf := bytes.NewBuffer(data)
	dec := gob.NewDecoder(buf)
	if err := dec.Decode(&result); err != nil {
		fmt.Println(err)
	}
	return result
}

// JsonToString 序列化为json
func JsonToString(obj any) string {
	if b, err := json.Marshal(obj); err != nil {
		log.Println("[ERROR] JSON序列化失败: ", err.Error())
		return ""
	} else {
		return string(b)
	}
}

// JsonParse 将 JSON 字符串反序列化为指定类型的对象
func JsonParse[T any](str string) (T, error) {
	var obj T

	str = strings.TrimSpace(str)
	if str == "" || !(str[0] == '{' && str[len(str)-1] == '}') {
		return obj, errors.New("JSON 字符串不能为空")
	}

	err := json.Unmarshal([]byte(str), &obj)
	if err != nil {
		log.Println("[ERROR] JSON 反序列化失败: ", err.Error())
		return obj, err
	}

	return obj, nil
}

// JsonParseArray 解析 JSON 数组到切片
func JsonParseArray[T any](str string) ([]T, error) {
	var arr []T

	str = strings.TrimSpace(str)
	if str == "" || !(str[0] == '[' && str[len(str)-1] == ']') {
		return arr, errors.New("JSON 字符串不能为空")
	}

	if err := json.Unmarshal([]byte(str), &arr); err != nil {
		return nil, fmt.Errorf("JSON 数组解析失败: %w", err)
	}
	return arr, nil
}

/* 字符串相关 */

// LowerFirst 首字母小写
func LowerFirst(s string) string {
	if s == "" {
		return ""
	}
	r := []rune(s)
	r[0] = unicode.ToLower(r[0])
	return string(r)
}

// UpperFirst 首字母大写
func UpperFirst(s string) string {
	if s == "" {
		return ""
	}
	r := []rune(s)
	r[0] = unicode.ToUpper(r[0])
	return string(r)
}

// 预编译正则表达式（匹配首尾非\w字符）
var nonWordRegex = regexp.MustCompile(`^\W+|\W+$`)

// TrimNonWChars 去除字符串首尾的非\w的字符
func TrimNonWChars(s string) string {
	return nonWordRegex.ReplaceAllString(s, "")
}

func main() {

	file := Try(func() (*os.File, error) {
		return os.Open("example.txt")
	})

	stat := Try(func() (os.FileInfo, error) {
		return file.Stat()
	})

	fmt.Println(file)
	fmt.Println(stat)
}
